﻿#include "study08.h"

// C/C++ 标准库学习网站：https://legacy.cplusplus.com
// C/C++ 微软(Visual Studio)中文学习网站：https://learn.microsoft.com/zh-cn/cpp/cpp/?view=msvc-170

using namespace std; // 标准库命名空间声明

struct Person {
	const char* p_name;
	short p_age;
	float p_height;

	Person() : p_name(""), p_age(0), p_height(0.0f) {}
	Person(const char* name, int age, float height)
		: p_name(name), p_age(age), p_height(height) {
	}

	bool operator<(const Person& p) const { // 重载小于号运算符
		if (p_age < p.p_age) return true;
		else if (p_age > p.p_age) return false;
	}
	bool operator>(const Person& p) const { // 重载大于号运算符
		if (p_age > p.p_age) return true;
		else if (p_age < p.p_age) return false;
	}

	friend ostream& operator<<(ostream& pos, const Person& p); // 友元函数声明
};

ostream& operator<<(ostream& pos, const Person& p) { // 重载输出运算符
	pos << "姓名：" << p.p_name << "    年龄：" << p.p_age << "    身高：" << p.p_height;
	return pos;
	// 这个函数在调用时 ostream& 作为第一个参数被隐式地传递给了重载的 << 运算符。
}


//static void print_person(const Person& p) {
//	cout << "姓名：" << p.p_name << " 年龄：" << p.p_age << " 身高：" << p.p_height << endl;
//}

static void arr_in_stick() {
	// 一维数组创建：
	int arr1[5] = { 1, 2, 3, 4, 5 };
	// 二维数组创建：
	int arr2[3][2] = { {1, 2}, {3, 4}, {5, 6} }; // 这种方式创建的数组是连续存储的
	// 三维数组创建：
	int arr3[2][3][2] = { { {1, 2}, {3, 4}, {5, 6} }, { {7, 8}, {9, 10}, {11, 12} } };

	// 输出数组内容：
	cout << "一维数组：" << endl;
	for (int i = 0; i < 5; i++)
		cout << arr1[i] << " ";
	cout << endl;

	cout << "二维数组：" << endl;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 2; j++)
			cout << arr2[i][j] << " ";
		cout << endl;
	}

	cout << "三维数组：" << endl;
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			for (int k = 0; k < 2; k++)
				cout << arr3[i][j][k] << " ";
			cout << endl;
		}
		if (i >= 1) break; // 输出前两层空行
		cout << endl;
	}
}

void test_multilayer_array()
{
	arr_in_stick();

	// 堆区二维数组：
	cout << "堆区二维数组：" << endl;
	float** arr_2d = new float* [9]; // 二维数组，指针数组 int*[10] 的数组指针 arr_2d
	// 为二维数组分配内存空间
	for (int i = 0; i < 9; i++)
		arr_2d[i] = new float[9]; // 为每行（每个指针）分配内存空间
	// 输入、输出二维数组内容
	for (int i = 0; i < 9; i++) {
		for (int j = 0; j < 9; j++) {
			arr_2d[i][j] = (i + 1) + (j + 1) / 10.0f; // 赋值
			cout << arr_2d[i][j] << "   ";
		}
		cout << endl;
	}
	// 释放二维数组内存空间
	for (int i = 0; i < 9; i++)
		delete[] arr_2d[i]; // 删除每行内存空间
	delete[] arr_2d; // 删除二维数组指针数组

	// 三维数组：
	cout << "堆区三维数组：" << endl;
	int*** arr_3d = new int** [3]; // 三维数组，指针数组 int** 的数组指针 arr_3d
	// 为三维数组分配内存空间并输入、输出三维数组内容
	for (int i = 0; i < 3; i++)
	{
		arr_3d[i] = new int* [3]; // 为每层（每个二级指针）分配内存空间
		for (int j = 0; j < 3; j++)
		{
			arr_3d[i][j] = new int[3]; // 为每行（每个一级指针）分配内存空间
			for (int k = 0; k < 3; k++) {
				arr_3d[i][j][k] = (i + 1) * 100 + (j + 1) * 10 + (k + 1); // 赋值
				cout << arr_3d[i][j][k] << "  ";
			}
			cout << endl;
		}
		if (i >= 2) break; // 输出前两层空行
		cout << endl;
	}
	// 释放三维数组内存空间
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++)
			delete[] arr_3d[i][j]; // 删除每行内存空间
		delete[] arr_3d[i]; // 删除每层内存空间
	}
	delete[] arr_3d; // 删除三维数组指针数组

	//将二维数组优化为一维数组
	cout << "将二维数组优化为一维数组，优化后的一维数组：" << endl;
	float* arr1 = new float[5 * 5]; // 一维数组，有 5 * 5 个元素
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 5; j++) {
			arr1[i * 5 + j] = (i + 1) + (j + 1) / 10.0f; // 赋值
			cout << arr1[i * 5 + j] << "    "; // 输出
		}
		cout << endl;
	}
	delete[] arr1; // 删除一维数组
}

void test_sort()
{
	// 数组排序：
	int arr1[5] = { 5, 3, 1, 4, 2 };
	sort(arr1, arr1 + 5); // 整数数组排序，默认从小到大排序
	cout << "整型数组排序后：" << endl;
	for (int i = 0; i < 5; i++)
		cout << arr1[i] << " ";
	cout << endl;

	// 自定义整数排序：
	int arr2[8] = { 5, 2, 1, 7, 3, 4, 6, 8 };
	sort(arr2, arr2 + 8, [&](int a, int b) -> bool {
		if (a == 1) return false; // 元素 1 排在最后面，因为 1 最小，想要排到后面就返回 false 表示 a > b 为 true
		if (b == 1) return true; // 元素 1 排在最后面
		return a < b; // 元素从小到大排序
		}); // 自定义整数排序，从大到小排序
	cout << "自定义整数排序后：" << endl;
	for (int i = 0; i < 8; i++)
		cout << arr2[i] << " ";
	cout << endl;

	// vector 排序：
	vector<string> vec1 = { "apple", "orange", "banana", "pear", "grape" };
	sort(vec1.begin(), vec1.end(), greater<string>()); // string 类型的 vector 排序，降序排序
	// greater<string>() 是一个函数对象，用来比较两个 string 类型的大小，返回 true 表示 a > b 为 true
	cout << "vector 排序后：" << endl;
	/*for (vector<string>::iterator it = vec1.begin(); it != vec1.end(); it++)
		cout << *it << " ";*/
		/*for (auto it = vec1.begin(); it != vec1.end(); it++)
			cout << *it << " ";*/
	for (auto it : vec1) // range for 语法
		cout << it << " ";
	cout << endl;

	// 自定义结构体排序：
	Person arr3[4] = {
		Person("Tom", 25, 107.5f),
		Person("Jerry", 20, 116.5f),
		Person("Lily", 22, 97.3f),
		Person("Lucy", 23, 106.8f)
	};
	// 字母顺序：abcdefghijklmnopqrstuvwxyz
	sort(arr3, arr3 + 4, [&](Person a, Person b) -> bool {
		return a.p_name < b.p_name; // 按照名字升序排序
	});
	cout << "C++ 自定义结构体 sort 排序名字后：" << endl;
	for (int i = 0; i < 4; i++)
		cout << arr3[i] << endl;

	// 使用 <stdlib.h> 中的 qsort 函数实现自定义结构体排序
	qsort(arr3, 4, sizeof(Person), [](const void* a, const void* b) -> int {
		return int(((Person*)b)->p_name - ((Person*)a)->p_name); // 按照名字降序排序
		//std::string.c_str() 返回指向字符串的 const char* 指针，可以直接进行指针运算
	});
	cout << "C 自定义结构体 qsort 排序名字后：" << endl;
	for (int i = 0; i < 4; i++)
		cout << arr3[i] << endl;
}